import React from 'react';
import './app.css'

// react hook前函数式组件没有状态
// 初始化状态 -- 读取状态 -- 修改状态 -- 影响视图
class TestComponent extends React.Component {
  // 初始化组件状态
  state = {
    name: "teacher"
  }

  changeName = () => {
    // 不允许直接修改赋值
    // this.state.name = "小明"

    // 通过setState方法才能响应式双向更新
    this.setState({
      name: "小明"
    })
  }

  render() {
    return (
      <div>
        TestComponent
        {/* 读取状态 */}
        当前name：{this.state.name}
        <div onClick={this.changeName}>修改name</div>
      </div>
    )
  }
}

class Counter extends React.Component {
  state = {
    count: 0,
    list: [1, 2, 3],
    deleteList: [1, 2, 3],
    person: {
      name: "xiaoming",
      age: 18
    }
  }

  countAdd = () => {
    this.setState({
      count: this.state.count + 1,
      // 新增数据
      list: [...this.state.list, 4],
      person: {
        ...this.state.person,
        sex: "male"
      },
      // 删除数据
      deleteList: this.state.deleteList.filter(item => item !== 2),
    }, () => {
      // setState异步更新
      console.log("回调", this.state)
    })
    // state还没更新
    console.log("顺序", this.state)
  }

  render() {
    return (
      <div>
        <p>{this.state.count}</p>
        <button onClick={this.countAdd}>click</button>
      </div>
    )
  }

}

class ThisPoint1 extends React.Component {
  // 解决this方向为undefined的问题
  constructor() {
    super()
    // 在组件初始化时就把this指向强行绑定
    this.handle = this.handle.bind(this)
  }

  handle() {
    // 不用箭头函数会导致this指向为空
    console.log(this)
  }

  render() {
    return (
      <button onClick={this.handle}>this指向问题1</button>
    )
  }

}

class ThisPoint2 extends React.Component {

  handle() {
    // 不用箭头函数会导致this指向为空
    console.log(this)
  }

  render() {
    return (
      // 利用箭头函数沿用父级函数render的this，确保指向
      <button onClick={() => this.handle()}>this指向问题2</button>
    )
  }

}

function App() {
  return (
    <div className="App">
      <TestComponent></TestComponent>
      <Counter></Counter>
      <ThisPoint1></ThisPoint1>
      <ThisPoint2></ThisPoint2>
    </div>
  );
}

export default App;
